package com.dongdongshop.config;

import com.alibaba.dubbo.config.annotation.Reference;
import com.dongdongshop.pojo.pay.TbPayLog;
import com.dongdongshop.service.PayLogService;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;

@RocketMQTransactionListener(txProducerGroup = "tx-stockCount")//事物消息
public class TxMessageCallback implements RocketMQLocalTransactionListener {

    @Reference
    private PayLogService payLogService;
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 执行本地事物的方法，减库存方法
     * @param msg
     * @param o
     * @return
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object o) {
      //执行本地事物
        TbPayLog payLog=(TbPayLog)o;//其他类型转实体类

        String message = new String((byte[]) msg.getPayload());
        System.out.println("将要发送的消息为: "+message);
        System.out.println("本地事物需要的参数 ："+o.toString());
        try {
            //保存数据库
            payLogService.updatePayByOutTradeNo(payLog);
            //数据减一
            System.out.println("正在执行本地事物+++++");
        }catch (Exception e){
            e.printStackTrace();
            //处理异常返回ROLLBACK 将消息id保存到redis中
            redisTemplate.opsForValue().set(msg.getHeaders().get("TRANSACTION_ID"), "2");
            return RocketMQLocalTransactionState.ROLLBACK;//异常回归，讲刚才发出去的半消息回滚
        }
        //执行成功 可以将消息的id保存到redis中 为了事物的回查
        System.out.println("id"+msg.getHeaders().getId());
        redisTemplate.opsForValue().set(msg.getHeaders().get("TRANSACTION_ID"), "1");
        return RocketMQLocalTransactionState.COMMIT;//讲发出去的半信息,放入对垒，消费者可以消费词消息
    }

    /**
     * 事物回查
     * @param msg
     * @return
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
        //回查处理状态 如果消息已经出了 提交，否则回查
        //获取消息id
       // System.out.println(msg.getHeaders().getId());
        //根据id 从redis中获取，判断消息处理状态，比如1:表示已经处理 2：表示 消息异常
        String status = (String) redisTemplate.opsForValue().get(msg.getHeaders().get("TRANSACTION_ID").toString());
        if ("1".equals(status)) {
            return RocketMQLocalTransactionState.COMMIT;
        } else if ("2".equals(status)) {
            //继续处理，或者直接回滚
            return RocketMQLocalTransactionState.ROLLBACK;
        } else {
            return RocketMQLocalTransactionState.UNKNOWN;
        }
    }
}
